package com.ajx.blog.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import com.ajx.blog.entity.Admin;
import com.ajx.blog.entity.Menu;
import com.ajx.blog.entity.Roles;
import com.ajx.blog.service.api.AdminService;
import com.ajx.blog.service.api.MenuService;
import com.ajx.blog.service.api.RolesService;
import com.ajx.blog.util.FileUtil;

import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping(value = "/blog/admin")
public class AdminController {

    private Logger logger = LoggerFactory.getLogger(AdminController.class);

    @Reference(url = "dubbo://localhost:20880")
    private AdminService adminService;

    @Reference(url = "dubbo://localhost:20880")
    private RolesService rolesService;

    @Reference(url = "dubbo://localhost:20880")
    private MenuService menuService;

    /**
     * @param {MultipartFile} imgurl 图像
     * @param {Admin}         admin 新添加的管理员用户
     * @return {Object}
     * 
     * @description: 添加新管理员
     */
    @PostMapping("/admin")
    public Object insertOneAdmin(@RequestParam(value = "imgurl", required = false) MultipartFile imgurl, Admin admin)
            throws FileNotFoundException {
        admin.setAdminHeadimg("/");
        Map<String, Object> returnMap = new HashMap<>();
        if (imgurl != null && imgurl.getSize() > 0) {// 文件上传
            // 原文件名
            String submittedFileName = imgurl.getOriginalFilename();
            String fileName = FileUtil.getFileName(submittedFileName);
            // 获取文件上传路径
            String realPath = ResourceUtils.getURL("classpath:").getPath();
            String datePath = FileUtil.getFileDatePath();
            String filePath = realPath + "/static/upload/" + datePath;
            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            if (!imgurl.isEmpty()) {
                try (FileOutputStream fos = new FileOutputStream(filePath + "/" + fileName);
                        InputStream in = imgurl.getInputStream();) {
                    int b = 0;
                    while ((b = in.read()) != -1) {
                        fos.write(b);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            admin.setAdminHeadimg("upload/" + datePath + "/" + fileName);
        }
        logger.info("调用添加新管理员方法");
        if (adminService.insertOneAdmin(admin)) {
            returnMap.put("code", 0);
            returnMap.put("msg", "添加管理员成功");
            logger.info("添加管理员成功");
        } else {
            returnMap.put("code", -1);
            returnMap.put("msg", "添加管理员失败");
            logger.info("添加管理员失败");
        }
        return returnMap;
    }

    /**
     * @param {Integer} adminId 管理员id
     * @return {Object}
     * 
     * @description: 通过id删除一名管理员用户
     */
    @DeleteMapping("/admin/{adminId}")
    public Object deleteOneAdmin(@PathVariable("adminId") Integer adminId) {
        Map<String, Object> returnMap = new HashMap<>();
        if (adminId != null && adminId > 0) {
            if (adminService.deleteOneAdmin(adminId)) {
                returnMap.put("code", 0);
                returnMap.put("msg", "删除管理员用户成功");
                logger.info("删除管理员用户成功");
            } else {
                returnMap.put("code", -1);
                returnMap.put("msg", "删除管理员用户失败");
                logger.info("删除管理员用户失败");
            }
            return returnMap;
        } else {
            returnMap.put("code", -1);
            returnMap.put("msg", "删除管理员用户失败,管理员id不能为空");
            logger.info("删除管理员用户失败,管理员id不能为空");
            return returnMap;
        }
    }

    /**
     * @param {Integer}   adminId 管理员ID
     * @param {Integer[]} roleIDs 角色ID数组
     * @return {Object}
     * 
     * @description: 更新管理员角色
     */
    @PutMapping("/roleAdminPower/{adminId}/{roleIds}")
    public Object updateRoleAdminPower(@PathVariable("adminId") Integer adminId,
            @PathVariable("roleIDs") Integer[] roleIds) {
        Map<String, Object> returnMap = new HashMap<>();
        if (adminService.updateRolesAdminById(adminId, roleIds)) {
            returnMap.put("code", 0);
            returnMap.put("msg", "更新管理员角色成功");
            logger.info("更新管理员角色成功");
        } else {
            returnMap.put("code", -1);
            returnMap.put("msg", "更新管理员角色失败");
            logger.info("更新管理员角色失败");
        }
        return returnMap;
    }

    /**
     * @param {*} adminId 管理员ID
     * @param {*} session 作用域
     * @return {Object}
     * 
     * @description: 通过ID查询管理员角色,在查询所有角色,
     *               如果管理员有此角色,则将allRoleList的Description字段设为true(String)
     */
    @GetMapping("/roleAdminPower/{adminId}")
    public Object roleAdminPower(@PathVariable("adminId") Integer adminId, HttpSession session) {
        Map<String, Object> returnMap = new HashMap<>();
        if (adminId == null) {
            returnMap.put("code", -1);
            returnMap.put("msg", "通过ID查询管理员角色失败,原因:aid为空");
            logger.info("通过ID查询管理员角色失败");
            return returnMap;
        }
        List<Roles> adminRoleList = rolesService.selectRoleByAdmin(adminId);
        List<Roles> allRoleList = rolesService.selectAllRole();
        for (Roles r1 : allRoleList) {
            for (Roles r2 : adminRoleList) {
                if (r2.getId() == r1.getId()) {
                    r1.setDescription("true");
                    break;
                }
            }
        }
        returnMap.put("code", 0);
        returnMap.put("data", allRoleList);
        returnMap.put("msg", "通过ID查询管理员角色成功");
        logger.info("通过ID查询管理员角色成功");
        return returnMap;
    }

    /**
     * @param {Integer} page 当前页码数
     * @return {Object}
     * 
     * @description: 查询管理员列表
     */
    @GetMapping("/roleAdminList/{page}")
    public Object roleAdminList(@PathVariable("page") Integer page) {
        Map<String, Object> returnMap = new HashMap<>();
        if (page == null || page < 0) {
            page = 1;
        }
        returnMap.put("code", 0);
        returnMap.put("data", adminService.findAllAdminList(page));
        returnMap.put("msg", "查询管理员列表成功");
        logger.info("查询管理员列表成功");
        return returnMap;
    }

    /**
     * @param {Roles} role 添加的新角色
     * @return {Object}
     * 
     * @description: 添加新角色
     */
    @PostMapping("/role")
    public Object insertOneRole(@RequestBody Roles role) {
        Map<String, Object> returnMap = new HashMap<>();
        logger.info("调用添加新角色方法");
        if (rolesService.insertOneRole(role)) {
            returnMap.put("code", 0);
            returnMap.put("msg", "添加角色成功");
            logger.info("添加角色成功");
        } else {
            returnMap.put("code", -1);
            returnMap.put("msg", "添加角色失败");
            logger.info("添加角色失败");
        }
        return returnMap;
    }

    /**
     * @param {Integer} roleId 待删除的角色ID
     * @return {Object}
     * 
     * @description: 删除角色
     */
    @DeleteMapping("/role/{roleId}")
    public Object deleteOneRole(@PathVariable("roleId") Integer roleId) {
        Map<String, Object> returnMap = new HashMap<>();
        String errorMsg = "删除角色失败";
        String successMsg = "删除角色成功";
        logger.info("调用删除角色方法");
        if (roleId == null) {
            returnMap.put("code", -1);
            returnMap.put("msg", "请选择一个角色");
            logger.info(errorMsg);
        } else if (rolesService.removeById(roleId)) {
            returnMap.put("code", 0);
            returnMap.put("msg", successMsg);
            logger.info(successMsg);
        } else {
            returnMap.put("code", -1);
            returnMap.put("msg", errorMsg);
            logger.info(errorMsg);
        }
        return returnMap;
    }

    /**
     * @param {Integer}   roleId 角色ID
     * @param {Integer[]} menuIds 菜单ID数组
     * @return {Object}
     * 
     * @description: 更新角色权限
     */
    @PutMapping("/adminMenuPower/{roleId}/{menuIds}")
    public Object updateAdminMenuPower(@PathVariable("roleId") Integer roleId,
            @PathVariable("ids") Integer[] menuIds) {
        Map<String, Object> returnMap = new HashMap<>();
        if (rolesService.updateAdminMenuById(roleId, menuIds)) {
            returnMap.put("code", 0);
            returnMap.put("msg", "更新角色权限成功");
            logger.info("更新角色权限成功");
        } else {
            returnMap.put("code", -1);
            returnMap.put("msg", "更新角色权限失败");
            logger.info("更新角色权限失败");
        }
        return returnMap;
    }

    /**
     * @param {Integer} page 当前页码数
     * @return {Object}
     * 
     * @description: 查询角色列表
     */
    @GetMapping("/roleList/{page}")
    public Object roleList(@PathVariable("page") Integer page) {
        Map<String, Object> returnMap = new HashMap<>();
        if (page == null || page < 0) {
            page = 1;
        }
        returnMap.put("code", 0);
        returnMap.put("data", rolesService.selectAllRoleByLimit(page));
        returnMap.put("msg", "查询角色列表成功");
        logger.info("查询角色列表成功");
        return returnMap;
    }

    /**
     * @param {Integer}     roleId 角色ID
     * @param {HttpSession} session
     * @return {Object}
     * 
     * @description: 通过ID查询角色权限,在查询所有权限
     */
    @GetMapping("/roleMenuPower/{roleId}")
    public Object roleMenuPower(@PathVariable("roleId") Integer roleId, HttpSession session) {
        // 返回值data
        Map<String, Object> returnMap = new HashMap<>();
        // 返回值中data值
        Map<String, Object> dataMap = new HashMap<>();
        // 加载待查询角色拥有权限 map
        Map<Integer, Object> waitroleMenuMap = menuService.selectAdminMenu(roleId);
        logger.info("[SUCCESS]加载待查询用户权限成功:{}", waitroleMenuMap);
        // 加载所有角色一级权限 list
        List<Menu> allfirstmenuList = (List<Menu>) session.getAttribute("allfirstmenuList");
        // 加载所有角色二级权限 map
        Map<Integer, List<Menu>> allsecondmenumap = (Map<Integer, List<Menu>>) session.getAttribute("allsecondmenumap");
        if (allfirstmenuList == null || allsecondmenumap == null) {
            // 查询条件
            Map<String, Object> pmap = new HashMap<>();
            allfirstmenuList = menuService.selectAllMenuByMap(pmap);
            allsecondmenumap = new HashMap<>();
            for (Menu firstmenu : allfirstmenuList) {
                pmap.put("parentId", firstmenu.getId());
                List<Menu> secondmenuList = menuService.selectAllMenuByMap(pmap);
                if (secondmenuList.size() > 0) {
                    allsecondmenumap.put(firstmenu.getId(), secondmenuList);
                }
            }
            logger.info("在数据库查询全部一级菜单list:{}", allfirstmenuList);
            logger.info("在数据库查询全部二级菜单map:{}", allsecondmenumap);
            session.setAttribute("allfirstmenuList", allfirstmenuList);
            session.setAttribute("allsecondmenumap", allsecondmenumap);
            logger.info("将全部一级菜单list存储到数据库中");
            logger.info("将全部二级菜单map存储到数据库中");
        } else {
            logger.info("在session中获取全部一级菜单list:{}", allfirstmenuList);
            logger.info("在session中获取全部二级菜单map:{}", allsecondmenumap);
        }
        dataMap.put("waitroleMenuMap", waitroleMenuMap);
        dataMap.put("firstmenuList", allfirstmenuList);
        dataMap.put("secondmenumap", allsecondmenumap);
        returnMap.put("code", 0);
        returnMap.put("data", dataMap);
        returnMap.put("msg", "加载角色权限列表成功");
        return returnMap;
    }

    /**
     * @param {Menu}        menu 菜单栏对象
     * @param {HttpSession} session 作用域
     * @return {Object}
     * 
     * @description: 添加一个菜单栏
     */
    @PostMapping("/menu")
    public Object insertOneMenu(@RequestBody Menu menu, HttpSession session) {
        Map<String, Object> returnMap = new HashMap<>();
        logger.info("调用添加菜单栏方法");
        if (menuService.insertOneMenu(menu)) {
            session.removeAttribute("allfirstmenuList");
            session.removeAttribute("allsecondmenumap");
            logger.info("从session中移除一级、二级菜单信息");
            returnMap.put("code", 0);
            returnMap.put("msg", "添加菜单栏成功");
            logger.info("添加菜单栏成功");
        } else {
            returnMap.put("code", -1);
            returnMap.put("msg", "添加菜单栏失败");
            logger.info("添加菜单栏失败");
        }
        return returnMap;
    }

    /**
     * @param {Integer}     mid 菜单栏ID
     * @param {HttpSession} session 作用域
     * @return {Object}
     * 
     * @description: 删除一个菜单栏
     */
    @DeleteMapping("/menu/{menuId}")
    public Object deleteOneMenu(@PathVariable("menuId") Integer menuId, HttpSession session) {
        Map<String, Object> returnMap = new HashMap<>();
        logger.info("调用删除菜单栏方法");
        if (menuId != null && menuId > 0) {
            if (menuService.removeById(menuId)) {
                session.removeAttribute("allfirstmenuList");
                session.removeAttribute("allsecondmenumap");
                logger.info("从session中移除一级、二级菜单信息");
                returnMap.put("code", 0);
                returnMap.put("msg", "删除菜单栏成功");
                logger.info("删除菜单栏成功");
            } else {
                returnMap.put("code", -1);
                returnMap.put("msg", "删除菜单栏失败");
                logger.info("删除菜单栏失败");
            }
        }
        return returnMap;
    }

    /**
     * @param {Menu}        menu 菜单栏对象
     * @param {HttpSession} session 作用域
     * @return {Object}
     * 
     * @description: 修改一个菜单栏
     */
    @PutMapping("/menu")
    public Object updateOneMenu(@RequestBody Menu menu, HttpSession session) {
        Map<String, Object> returnMap = new HashMap<>();
        logger.info("管理员调用修改菜单栏方法");
        if (menuService.updateOneMenu(menu)) {
            session.removeAttribute("allfirstmenuList");
            session.removeAttribute("allsecondmenumap");
            logger.info("从session中移除一级、二级菜单信息");
            returnMap.put("code", 0);
            returnMap.put("msg", "修改菜单栏成功");
            logger.info("管理员调用修改菜单栏方法成功");
        } else {
            returnMap.put("code", -1);
            returnMap.put("msg", "修改菜单栏失败");
            logger.info("管理员调用修改菜单栏方法:修改失败");
        }
        return returnMap;
    }

    /**
     * @param {HttpSession} session 作用域
     * @return {Object}
     * 
     * @description: 获取全部一级菜单栏信息
     */
    @GetMapping("/allFirstMenu")
    public Object getAllFirstMenu(HttpSession session) {
        Map<String, Object> returnMap = new HashMap<>();
        // 加载所有角色一级权限 list
        List<Menu> allfirstmenuList = (List<Menu>) session.getAttribute("allfirstmenuList");
        if (allfirstmenuList == null) {
            // 查询条件
            Map<String, Object> pmap = new HashMap<>();
            allfirstmenuList = menuService.selectAllMenuByMap(pmap);
            session.setAttribute("allfirstmenuList", allfirstmenuList);
            logger.info("将全部一级菜单list存储到数据库中");
        } else {
            logger.info("在session中获取全部一级菜单list:{}", allfirstmenuList);
        }
        returnMap.put("code", 0);
        returnMap.put("data", allfirstmenuList);
        returnMap.put("msg", "加载全部一级菜单列表成功");
        return returnMap;
    }

    /**
     * @param {Integer}     page 当前页码数
     * @param {HttpSession} session 作用域
     * @return {Object}
     * 
     * @description: 获取全部菜单栏信息
     */
    @GetMapping("/allMenu/{page}")
    public Object getAllMenu(@PathVariable("page") Integer page, HttpSession session) {
        Map<String, Object> returnMap = new HashMap<>();
        if (page == null || page < 0) {
            page = 1;
        }
        returnMap.put("code", 0);
        returnMap.put("data", menuService.selectAllMenuByLimit(page));
        returnMap.put("msg", "管理员查询所有菜单列表成功");
        logger.info("管理员查询所有菜单列表成功");
        return returnMap;
    }

    /**
     * @param {Integer}     menuId 菜单ID
     * @param {HttpSession} session 作用域
     * @return {Object}
     * 
     * @description: 通过id获取菜单栏信息
     */
    @GetMapping("/menu/{menuId}")
    public Object getOneMenu(@PathVariable("menuId") Integer menuId, HttpSession session) {
        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("code", 0);
        returnMap.put("data", menuService.selectOneMenu(menuId));
        returnMap.put("msg", "管理员通过id查询菜单成功");
        logger.info("管理员通过id查询菜单成功");
        return returnMap;
    }

}
